package com.byd.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import android.text.TextUtils;

public final class CommonUtils {
	private static Calendar sCalendar;
	private static SimpleDateFormat sDateFormat_dayTime;
	private static SimpleDateFormat sDateFormat_day;
	private static DecimalFormat sDecimalFormat_0;
	private static DecimalFormat sDecimalFormat_00;

	private static Calendar getCalendar() {
		if(sCalendar == null) {
			sCalendar = Calendar.getInstance();
		}
		return sCalendar;
	}

	private static SimpleDateFormat getDateFormat_day() {
		if(sDateFormat_day == null) {
			sDateFormat_day = new SimpleDateFormat("yyyy-MM-dd");
		}
		return sDateFormat_day;
	}

	private static SimpleDateFormat getDateFormat_dayTime() {
		if(sDateFormat_dayTime == null) {
			sDateFormat_dayTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		}
		return sDateFormat_dayTime;
	}

	private static DecimalFormat getDecimalFormat_0() {
		if(sDecimalFormat_0 == null) {
			sDecimalFormat_0 = new DecimalFormat("0");
		}
		return sDecimalFormat_0;
	}

	public static DecimalFormat getDecimalFormat_00() {
		if(sDecimalFormat_00 == null) {
			sDecimalFormat_00 = new DecimalFormat("0.0");
		}
		return sDecimalFormat_00;
	}

	public static long dayTimeToMillis(String time) throws Exception {
		final Calendar calendar = getCalendar();
		calendar.setTime(getDateFormat_dayTime().parse(time));
		return calendar.getTimeInMillis();
	}

	public static long dayToMillis(String day) throws Exception {
		final Calendar calendar = getCalendar();
		calendar.setTime(getDateFormat_day().parse(day));
		return calendar.getTimeInMillis();
	}

	public static String getDayTime(long timeMs) {
		return getDateFormat_dayTime().format(new Date(timeMs));
	}

	public static String getDay(long timeMs) {
		return getDateFormat_day().format(new Date(timeMs));
	}

	public static boolean isDay(long time) {
		final Calendar calendar = getCalendar();
		calendar.setTimeInMillis(time);
		final int hour = calendar.get(Calendar.HOUR_OF_DAY);
		return hour >= 6 && hour <= 18;
	}

	public static String getFileLength(long length) {
		float value;
		String unit;
		DecimalFormat format;
		if(length < 1024) {
			value = Math.max(length, 0);
			unit = "B";
			format = getDecimalFormat_0();
		}
		else if(length < 1024 * 1024l) {
			value = length / 1024f;
			unit = "KB";
			format = getDecimalFormat_0();
		}
		else if(length < 1024 * 1024 * 1024l) {
			value = length / (1024 * 1024f);
			unit = "MB";
			format = getDecimalFormat_00();
		}
		else if(length < 1024 * 1024 * 1024 * 1024l) {
			value = length / (1024 * 1024 * 1024f);
			unit = "GB";
			format = getDecimalFormat_00();
		}
		else {
			return "max size";
		}
		return format.format(value) + unit;
	}

	public static long getFolderSize(File folder) {
		if(folder != null) {
			final File[] files = folder.listFiles();
			if(files != null) {
				long size = 0;
				for (final File file : files) {
					if(file.isFile()) {
						size += file.length();
					}
					else {
						size += getFolderSize(file);
					}
				}
				return size;
			}
		}
		return 0;
	}

	public static boolean compare(Object o1, Object o2) {
		if(o1 == null) {
			return o2 == null;
		}
		return o1.equals(o2);
	}

	public static byte[] getBytes(InputStream inputStream) {
		ByteArrayOutputStream outputStream = null;
		try {
			outputStream = new ByteArrayOutputStream();
			final byte[] buffer = new byte[4096];
			int len = 0;
			while ((len = inputStream.read(buffer)) != -1) {
				outputStream.write(buffer, 0, len);
			}
			return outputStream.toByteArray();
		}
		catch (final Exception e) {
			Lg.printStackTrace(e);
			return null;
		}
		finally {
			try {
				if(outputStream != null) {
					outputStream.close();
				}
			}
			catch (final Exception e) {
				Lg.printStackTrace(e);
			}
		}
	}

	public static String flatBytes(byte[] data) {
		if(data == null) {
			return null;
		}
		return flatBytes(data, 0, data.length);
	}

	public static String flatBytes(byte[] data, int start, int count) {
		if(data == null || start < 0 || count <= 0) {
			return null;
		}
		int length = Math.min(Math.min(data.length, count), data.length - start);
		final StringBuilder builder = new StringBuilder();
		builder.append("[");
		String str;
		length += start;
		for (int i = start; i < length; i++) {
			builder.append("0x");
			str = Integer.toHexString(data[i] & 0xFF).toUpperCase();
			if(str.length() == 1) {
				builder.append(0);
				// str = "0" + str;
			}
			builder.append(str);
			if(i < length - 1) {
				builder.append(", ");
			}
		}
		builder.append("]");
		return builder.toString();
	}

	public static String flatInts(int[] data) {
		if(data == null) {
			return null;
		}
		return flatInts(data, 0, data.length);
	}

	public static String flatInts(int[] data, int start, int count) {
		if(data == null || start < 0 || count <= 0) {
			return null;
		}
		int length = Math.min(Math.min(data.length, count), data.length - start);
		final StringBuilder builder = new StringBuilder();
		builder.append("[");
		String str;
		length += start;
		for (int i = start; i < length; i++) {
			builder.append("0x");
			str = Integer.toHexString(data[i]).toUpperCase();
			if(str.length() == 1) {
				builder.append(0);
				// str = "0" + str;
			}
			builder.append(str);
			if(i < length - 1) {
				builder.append(", ");
			}
		}
		builder.append("]");
		return builder.toString();
	}

	public static byte[] arrayConnect(byte[] t1, byte t2) {
		return arrayConnect(t1, new byte[]{t2});
	}

	public static byte[] arrayConnect(byte[] t1, byte[] t2) {
		if(t1 == null) {
			return t2;
		}
		else if(t2 == null) {
			return t1;
		}
		final byte[] result = new byte[t1.length + t2.length];
		System.arraycopy(t1, 0, result, 0, t1.length);
		System.arraycopy(t2, 0, result, t1.length, t2.length);
		return result;
	}

	public static int[] arrayConnect(int[] t1, int t2) {
		return arrayConnect(t1, new int[]{t2});
	}

	public static int[] arrayConnect(int[] t1, int[] t2) {
		if(t1 == null) {
			return t2;
		}
		else if(t2 == null) {
			return t1;
		}
		final int[] result = new int[t1.length + t2.length];
		System.arraycopy(t1, 0, result, 0, t1.length);
		System.arraycopy(t2, 0, result, t1.length, t2.length);
		return result;
	}

	public static boolean isTextEmpty(String text) {
		if(TextUtils.isEmpty(text)) {
			return true;
		}
		return TextUtils.isEmpty(text.trim());
	}

	public static String parseSignature(byte[] signature) {
		try {
			final CertificateFactory factory = CertificateFactory.getInstance("X.509");
			
			final X509Certificate certificate = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(
					signature));
			final String signNumber = certificate.getSerialNumber().toString();
			// error("pubKey: " + pubKey);
			// error("signNumber: " + signNumber);
			return signNumber;
		}
		catch (final Exception e) {
			Lg.printStackTrace(e);
		}
		return null;
	}
	
	public static String getTimeString(int dur) {
		dur /= 1000;
		int hours = dur / 3600;
		int minutes = (dur - hours * 3600) / 60;
		int seconds = dur - hours * 3600 - minutes * 60;
		StringBuilder duration = new StringBuilder();
		if(hours > 0) {
			duration.append(hours + ":");
		}
		if(minutes > 9) {
			duration.append(minutes + ":");
		}
		else {
			if(hours > 0) {
				duration.append("0" + minutes + ":");
			}
			else {
				duration.append(minutes + ":");
			}
		}
		if(seconds > 9) {
			duration.append(seconds);
		}
		else {
			duration.append("0" + seconds);
		}
		return duration.toString();
	}
}
